package org.baeta.model;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Description
 *
 * @author <a href="mailto:rui.baeta@gmail.com">Rui Baeta</a>
 */
public class JSON2ModelFactory
{
    private static final Log LOG = LogFactory.getLog(JSON2ModelFactory.class);

    private static JSON2ModelFactory instance = new JSON2ModelFactory();

    public static JSON2ModelFactory getInstance()
    {
        return instance;
    }

    private JSON2ModelFactory()
    {
    }

    public static enum ClientResponseType
    {
        GEONAMES,
        STATUS,
        WEATHEROBSERVATIONS
    }

    public AbstractBean createBean(JSONObject jsonObject) throws Exception
    {
        AbstractBean bean = null;
        String[] names = JSONObject.getNames(jsonObject);
        if (names.length > 0)
        {
            // got something!
            String name = names[0];
            ClientResponseType type = ClientResponseType.valueOf(name.toUpperCase());

            switch (type)
            {
                case GEONAMES:
                    bean = createGeoName(jsonObject.getJSONArray("geonames"));
                    break;

                case WEATHEROBSERVATIONS:
                    bean = createWeatherObservation(jsonObject.getJSONArray("weatherObservations"));
                    break;

                case STATUS:
                    bean = createStatusMessage(jsonObject.getJSONObject("status"));
                    break;

                default:

            }
        }
        return bean;
    }

    public GeoName createGeoName(JSONArray jsonArray) throws Exception
    {
        GeoName geoName = new GeoName();
        if (jsonArray.length() > 0)
        {
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            geoName.setGeonameId(jsonObject.getInt("geonameId"));
            geoName.setIsoNumeric(jsonObject.getInt("isoNumeric"));
            geoName.setIsoAlpha3(jsonObject.getString("isoAlpha3"));
            geoName.setCountryCode(jsonObject.getString("countryCode"));
            geoName.setCountryName(jsonObject.getString("countryName"));
            geoName.setCurrencyCode(jsonObject.getString("currencyCode"));
            geoName.setFipsCode(jsonObject.getString("fipsCode"));
            geoName.setCapital(jsonObject.getString("capital"));
            geoName.setContinent(jsonObject.getString("continent"));
            geoName.setContinentName(jsonObject.getString("continentName"));
            geoName.setLanguages(jsonObject.getString("languages"));
            geoName.setNorth(jsonObject.getDouble("north"));
            geoName.setSouth(jsonObject.getDouble("south"));
            geoName.setEast(jsonObject.getDouble("east"));
            geoName.setWest(jsonObject.getDouble("west"));
            geoName.setPopulation(jsonObject.getLong("population"));
            geoName.setAreaInSqKm(jsonObject.getDouble("areaInSqKm"));
        }
        return geoName;
    }

    public WeatherObservation createWeatherObservation(JSONArray jsonArray) throws Exception
    {
        WeatherObservation weatherObservation = new WeatherObservation();
        if (jsonArray.length() > 0)
        {
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            weatherObservation.setObservation(jsonObject.getString("observation"));
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            weatherObservation.setObservationTime(df.parse(jsonObject.getString("datetime")));
            weatherObservation.setStationName(jsonObject.getString("stationName"));
            weatherObservation.setIcaoCode(jsonObject.getString("ICAO"));
            //weatherObservation.setCountryCode(jsonObject.getString("countryCode"));
            //weatherObservation.setElevation(jsonObject.getInt("elevation"));
            weatherObservation.setLatitude(jsonObject.getDouble("lat"));
            weatherObservation.setLongitude(jsonObject.getDouble("lng"));
            weatherObservation.setTemperature(jsonObject.getDouble("temperature"));
            weatherObservation.setDewPoint(jsonObject.getDouble("dewPoint"));
            weatherObservation.setHumidity(jsonObject.getDouble("humidity"));
            weatherObservation.setClouds(jsonObject.getString("clouds"));
            weatherObservation.setWeatherCondition(jsonObject.getString("weatherCondition"));
            weatherObservation.setWindSpeed(jsonObject.getString("windSpeed"));
            //weatherObservation.setWindDirection(jsonObject.getInt("windDirection"));
        }
        return weatherObservation;
    }

    public StatusMessage createStatusMessage(JSONObject jsonObject) throws Exception
    {
        StatusMessage statusMessage = new StatusMessage();
        statusMessage.setMessage(jsonObject.getString("message"));
        return statusMessage;
    }

}
